package com.xhwl.centiotdata.suppliersystem.eesd.iotnorth;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xhwl.centiotdata.constant.EesdConstant;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.cent.IDeviceCoreWebapiService;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.constant.cent.KeyConstant;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.eesd.*;
import com.xhwl.common.dto.cent.energy.EesdElectricDetailDTO;
import com.xhwl.common.dto.cent.ifm.IOTDeviceDTO;
import com.xhwl.common.dto.cent.iotdata.iotnorth.EnvIotNorthDataDTO;
import com.xhwl.common.dto.cent.iotdata.iotnorth.IotNorthDeviceShadowDTO;
import com.xhwl.common.dto.cent.iotdata.iotnorth.IotNorthShadowListRespDTO;
import com.xhwl.common.enums.device.DeviceOnlineStatusEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.cent.device.Device;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.query.cent.device.DevicePageQuery;
import com.xhwl.common.query.cent.device.DeviceQuery;
import com.xhwl.common.vo.devicecore.DeviceListVO;
import com.xhwl.common.vo.devicecore.ShadowListVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: iot北向物联网
 * @Copyright: Copyright (c) 2021  ALL RIGHTS RESERVED.
 * @Company: 深圳市兴海物联科技有限公司
 * @Author: gyc
 * @CreateDate: 2021/9/6 16:56
 * @UpdateDate: 2021/9/6 16:56
 * @UpdateRemark: init
 * @Version: 1.0
 */
@Slf4j
@Service
public class IotNorthHandler {

    @Resource
    private RedisUtils redisUtils;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    IDeviceCentService deviceCentService;

    @Resource
    private IDeviceCoreWebapiService iDeviceCoreWebapiService;

    /**
     *拉取iot北向接口获取的原始数据
     * @param config
     * @return
     */
    public List<OdsEnvironmentMetricsDTO> getOriginalData(DeviceProjSupplierCategory config) {
        Integer projectId = config.getProjectId();
        Integer productId = config.getProductId();
        List<String> deviceCodes = IotNorthApiUtil.getCodeList(config);

        List<OdsEnvironmentMetricsDTO> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(deviceCodes)) {
            return list;
        }
        for (String deviceCode : deviceCodes) {
            // 原始数据
            List<IotNorthDeviceShadowDTO> iotNorthDeviceShadows = IotNorthApiUtil.getShadowList(config, deviceCode);
            // 返回对象-观测时间是拉取时间
            List<EnvIotNorthDataDTO> envObject = IotNorthApiUtil.getEnvObject(productId, projectId, deviceCode, iotNorthDeviceShadows);
            List<OdsEnvironmentMetricsDTO> odsEnvironmentMetricsList = JSONObject.parseArray(JSON.toJSONString(envObject), OdsEnvironmentMetricsDTO.class);
            list.addAll(odsEnvironmentMetricsList);
        }
        return list;
    }

    /**
     *拉取iot北向接口获取的实时数据(环境判断)
     * @param config
     * @return
     */
    public List<EnvIotNorthDeviceDataDTO> getRealTimeData(DeviceProjSupplierCategory config) {
        Integer projectId = config.getProjectId();
        Integer productId = config.getProductId();
        List<String> deviceCodes = IotNorthApiUtil.getCodeList(config);

        List<EnvIotNorthDeviceDataDTO> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(deviceCodes)) {
            return list;
        }
        for (String deviceCode : deviceCodes) {
            List<IotNorthDeviceShadowDTO> iotNorthDeviceShadows = IotNorthApiUtil.getShadowList(config, deviceCode);
            List<EnvIotNorthDataDTO> envObject = IotNorthApiUtil.getEnvObject(productId, projectId, deviceCode, iotNorthDeviceShadows);
            // 原始数据过滤区分为等级
            List<EnvIotNorthDeviceDataDTO> envIotNorthDeviceDataVOS = IotNorthApiUtil.envJudgmentLevel(envObject);
            list.addAll(envIotNorthDeviceDataVOS);
        }
        return list;
    }

    /**
     * 环境同步原始设备状态数据到设备中台
     * @param config
     * @return
     */
    public List<Device> getUpdateOnlineStatus(DeviceProjSupplierCategory config) {
        List<OdsEnvironmentMetricsDTO> originalList = getOriginalData(config);
        JSONObject properties = config.getProperties();
        // 7	AirMonitorSensor	空气监测传感器
        Integer deviceTypeId = (Integer) properties.get("deviceTypeId");
        String dataStr = JSONObject.toJSONString(originalList);

        //log.info("环境同步原始设备状态数据到设备中台 开始： {}", dataStr);
        List<Device> list = new ArrayList<>();
        for (OdsEnvironmentMetricsDTO odsEnvironmentMetricsDTO : originalList) {
            Integer projectId = odsEnvironmentMetricsDTO.getProjectId();
            String deviceId = odsEnvironmentMetricsDTO.getDeviceId();
            Integer deviceStatus = odsEnvironmentMetricsDTO.getDeviceStatus();

            Device device = new Device();
            device.setProjectId(projectId);
            // 三方id
            device.setThirdDeviceId(deviceId);
            // 设备状态
            if (deviceStatus == 1) {
                device.setOnlineStatus(DeviceOnlineStatusEnum.ONLINE);
            } else {
                device.setOnlineStatus(DeviceOnlineStatusEnum.OFFLINE);
            }
            // 设备类型id
            device.setDeviceTypeId(deviceTypeId);
            list.add(device);
        }
        return list;
    }

    /**
     * 环境同步原始数据到设备中台
     * @param config
     * @return
     */
    public List<DeviceDTO> getPushEnvToDeviceData(DeviceProjSupplierCategory config) {
        List<OdsEnvironmentMetricsDTO> originalList = getOriginalData(config);
        // 系统模块id
        Integer prodCategoryId = config.getProdCategoryId();
        // 供应商系统产品id
        Integer productId = config.getProductId();
        JSONObject properties = config.getProperties();
        // 7	AirMonitorSensor	空气监测传感器
        Integer deviceTypeId = (Integer) properties.get("deviceTypeId");
        String dataStr = JSONObject.toJSONString(originalList);
        List<DeviceDTO> list = new ArrayList<>();
        for (OdsEnvironmentMetricsDTO odsEnvironmentMetricsDTO : originalList) {
            Integer projectId = odsEnvironmentMetricsDTO.getProjectId();
            String deviceId = odsEnvironmentMetricsDTO.getDeviceId();
            String name = odsEnvironmentMetricsDTO.getName();
            Integer deviceStatus = odsEnvironmentMetricsDTO.getDeviceStatus();

            DeviceDTO deviceDTO = new DeviceDTO();
            deviceDTO.setProjectId(projectId);
            deviceDTO.setCategoryId(prodCategoryId);
            deviceDTO.setName(name);
            // 三方id
            deviceDTO.setIotDeviceId(deviceId);
            deviceDTO.setThirdDeviceId(deviceId);
            // 设备状态
            deviceDTO.setOnlineStatus(deviceStatus);
            deviceDTO.setProductId(productId);
            // 设备类型id
            deviceDTO.setDeviceTypeId(deviceTypeId);
            list.add(deviceDTO);
        }
        return list;
    }


    /*****************************************iot 设备************************************************/
    public List<EesdElectricDetailDTO> getIotDataByCode(DeviceProjSupplierCategory config) {
        Integer projectId = config.getProjectId();
        JSONObject properties = config.getProperties();
        Integer deviceTypeId = properties.getInteger("deviceTypeId");
        List<Device> devices = IotNorthApiUtil.getDeviceListV2(config);
        List<EesdElectricDetailDTO> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(devices)) {
            return list;
        }
        devices.forEach(deviceDTO -> {
            Map<String, Object> map = IotNorthApiUtil.getShadowListV1(config, deviceDTO.getNodeId());
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            EesdElectricDetailDTO dto = new EesdElectricDetailDTO();
            dto.setProjectId(projectId);
            dto.setDeviceId(deviceDTO.getNodeId().toString());
            dto.setRate(0.0);
            dto.setDeviceType(deviceTypeId);
            dto.setTime(new Date());
            dto.setJsonFieldFlag(false);
            EesdElectricDetailDTO.ValueEntity ValueEntity =new EesdElectricDetailDTO.ValueEntity();
            ValueEntity.setValue(Double.valueOf(map.getOrDefault("all_elec",0).toString()));
            dto.setValue(ValueEntity);
            log.info("电表映射字段map：{} ，mapJson:{}", JSONObject.toJSONString(map), JSONObject.toJSONString(dto));
            if (!Objects.isNull(ValueEntity)) {
                list.add(dto);
            }
        });
        log.info("拉取iot设备数据完成");
        return list;
    }


    /*****************************************处理设备属性数据************************************************/


    public List<IceStorageAirDTO> getIceStorageAirData(DeviceProjSupplierCategory config) {
        Integer projectId = config.getProjectId();
        JSONObject properties = config.getProperties();
        Integer deviceTypeId = properties.getInteger("deviceTypeId");
        Integer airConstant = Optional.ofNullable(properties.getInteger("air")).orElse(0);
        Integer iceConstant = Optional.ofNullable(properties.getInteger("ice")).orElse(0);

        Integer productId = config.getProductId();
        List<String> deviceCodes = devicesCodeListV1(config, deviceTypeId);
        List<IceStorageAirDTO> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(deviceCodes)) {
            return list;
        }
        LocalDateTime now = LocalDateTime.now();
        //String key = new StringBuilder(KeyConstant.EESD_DEVICE_IDS_MAP).append(projectId).append(":").append(productId).toString();
        for (String deviceCode : deviceCodes) {
            Map<String, Object> map = IotNorthApiUtil.getShadowListV1(config, deviceCode);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
            IceStorageAirDTO dto = null;
            try {
                dto = objectMapper.readValue(JSONObject.toJSONString(map), IceStorageAirDTO.class);
            } catch (Exception e) {
                log.error("Parse exception: {}", e.getMessage());
            }
            //log.info("冰蓄冷映射字段map：{} ，IceStorageAirDTO:{}", JSONObject.toJSONString(map), JSONObject.toJSONString(dto));
            if (!Objects.isNull(dto)) {
                //String hashKey = deviceCode;
                /*Integer deviceId = Optional.ofNullable(redisUtils.hmGet(key, hashKey))
                        .map(d -> {
                            return JSONObject.parseObject(JSONObject.toJSONString(d), DeviceDTO.class).getId();
                        }).orElse(-1);
                log.info("======>冰蓄冷处理设备id<======:{}",deviceId);
                dto.setDeviceId(deviceId);*/
                dto.setProjectId(projectId);
                dto.setThirdDeviceId(deviceCode);
                dto.setUpdateTime(now);
                // todo 特殊处理
                BigDecimal divisor = new BigDecimal("200");
                BigDecimal iceCapacityPercentage = (dto.getIceCapacityPercentage1().add(dto.getIceCapacityPercentage2())).divide(divisor,2,RoundingMode.HALF_UP);
                dto.setStorageTime(iceCapacityPercentage.multiply(new BigDecimal(iceConstant)).setScale(2, RoundingMode.HALF_UP));
                dto.setMeltingTime((BigDecimal.ONE.subtract(iceCapacityPercentage)).multiply(new BigDecimal(airConstant)).setScale(2, RoundingMode.HALF_UP));
                dto.setValveStatus3(dto.getValveStatus3Off());
                dto.setValveStatus4(dto.getValveStatus4Off());
                dto.setValveStatus5(dto.getValveStatus5Off());
                dto.setValveStatus6(dto.getValveStatus5Off());
                if (dto.getIceStorageEndFlag().compareTo(BigDecimal.ZERO) == 0) {
                    dto.setIceStorageEnd(0);
                } else {
                    dto.setIceStorageEnd(1);
                }
                Integer tankHiAlarm = dto.getTankHiAlarm();
                Integer tankLowAlarm = dto.getTankLowAlarm();
                if (tankHiAlarm != 1 && tankLowAlarm != 1) {
                    dto.setTankStatus(0);
                } else if (tankHiAlarm == 1){
                    dto.setTankStatus(1);
                } else {
                    dto.setTankStatus(2);
                }
                dto.setCoolTotal(dto.getColdStorage());
                dto.setUnCoolTotal(dto.getColdMelting());
                list.add(dto);
            }
        }
        return list;
    }

    /**
     *
     * 获取电表读数信息
     * @param config 集成配置
     * @author YW
     * @date 2023/6/19 10:33
     * @return java.util.List
     */
    public List<EesdElectricDetailDTO> getIotDataByCodeV2(DeviceProjSupplierCategory config) {
        List<Device> devices = getDeviceListV2(config);
        if (CollectionUtils.isEmpty(devices)) {
            return null;
        }
        Map<String, Double> allElecMaps = new HashMap<>();
        devices.stream().forEach(device -> {
            Map<String, Object> attr = getDeviceAttribute(device.getNodeId());
            if (Objects.nonNull(attr)) {
                if (attr.containsKey("online") && "true".equals(attr.get("online"))) {
                    device.setOnlineStatus(DeviceOnlineStatusEnum.ABNORMAL);
                }
                // 电度属性
                if (attr.containsKey("all_elec") && Objects.nonNull(attr.get("all_elec"))) {
                    allElecMaps.put(device.getNodeId(), Double.parseDouble(attr.get("all_elec").toString()));
                }
            }
        });
        List<EesdElectricDetailDTO> list = new ArrayList<>();
        Integer deviceTypeId = config.getProperties().getInteger(EesdConstant.EESD_DEVICE_TYPE_ID);
        // 获取存在抄表记录的数据
        DevicePageQuery devicePageQuery = new DevicePageQuery();
        devicePageQuery.setProjectId(config.getProjectId());
        devicePageQuery.setDeviceTypeId(deviceTypeId);
        List<DeviceDTO> deviceDtos = deviceCentService.listDevice(null, devicePageQuery);
        Map<Integer, DeviceDTO> deviceMaps = null;
        if (!CollectionUtils.isEmpty(deviceDtos)) {
            deviceMaps = deviceDtos.stream().collect(Collectors.toMap(DeviceDTO::getId, Function.identity(), (v1, v2) -> v2));
        }
        Map<Integer, DeviceDTO> finalDeviceMaps = deviceMaps;
        devices.forEach(e -> {
            EesdElectricDetailDTO ele = new EesdElectricDetailDTO();
            ele.setProjectId(e.getProjectId());
            ele.setDeviceId(e.getNodeId());
            ele.setRate(0.0);
            // 修改设备后的倍率 否则后期在对比上月 上年是能耗用量不准确问题
            if (!CollectionUtils.isEmpty(finalDeviceMaps) && finalDeviceMaps.containsKey(e.getId())) {
                JSONObject attributeJson = finalDeviceMaps.get(e.getId()).getAttributeJson();
                if (Objects.nonNull(attributeJson) && attributeJson.containsKey("deviceRate") && attributeJson.getDouble("deviceRate") > 0) {
                    ele.setRate(attributeJson.getDouble("deviceRate"));
                }
            }
            ele.setDeviceType(deviceTypeId);
            ele.setTime(new Date());
            ele.setJsonFieldFlag(false);
            log.info("电表映射字段mapJson:{}, 封装数据结果：{}", JSONObject.toJSONString(allElecMaps), JSON.toJSONString(ele));
            EesdElectricDetailDTO.ValueEntity ValueEntity =new EesdElectricDetailDTO.ValueEntity();
            ValueEntity.setValue(BigDecimal.ZERO.doubleValue());
            if (allElecMaps.containsKey(e.getNodeId())) {
                ValueEntity.setValue(allElecMaps.get(e.getNodeId()));
            }
            ele.setValue(ValueEntity);
            list.add(ele);
        });
        return list;
    }


    /**
     *
     * 获取电表设备ID
     * @param config 配置信息
     * @author YW
     * @date 2023/6/19 10:33
     * @return java.util.List
     */
    public  List<Device> getDeviceListV2(DeviceProjSupplierCategory config) {
        if (!config.getProperties().containsKey(EesdConstant.PRODUCT_CODE)
                || !config.getProperties().containsKey(EesdConstant.PRODUCT_ID)) {
            log.info("拉取iot兴海水电表集成配置缺少productId或productCode属性");
            return null;
        }
        DeviceListVO deviceListVO =  new DeviceListVO();
        deviceListVO.setProductCode(config.getProperties().getString(EesdConstant.PRODUCT_CODE));
        deviceListVO.setProjectId(Arrays.asList(Long.valueOf(config.getProjectId())));
        Integer productId = config.getProperties().getInteger(EesdConstant.PRODUCT_ID);
        Integer deviceTypeId = config.getProperties().getInteger(EesdConstant.EESD_DEVICE_TYPE_ID);
        JSONObject jsonObject = iDeviceCoreWebapiService.deviceList(deviceListVO);
        // 获取设备信息
        if (CollectionUtils.isEmpty(jsonObject) || !jsonObject.containsKey(EesdConstant.RESULT)) {
            log.info("拉取iot兴海水电表设备数据为空");
            return null;
        }
        JSONObject result = jsonObject.getJSONObject(EesdConstant.RESULT);
        if (Objects.isNull(result) || !result.containsKey(EesdConstant.RECORDS) || Objects.isNull(result.get(EesdConstant.RECORDS))) {
            log.info("拉取iot兴海水电表设备数据为空");
            return null;
        }
        List<IOTDeviceDTO> deviceDTOS = result.getJSONArray(EesdConstant.RECORDS).toJavaList(IOTDeviceDTO.class);
        log.info("拉取iot兴海水电表设备数量：{}", deviceDTOS.size());
        // 封装设备信息
        List<Device> devices = new ArrayList<>();
        deviceDTOS.stream().forEach(e -> {
            Device device = new Device();
            device.setId(e.getId());
            device.setProjectId(config.getProjectId());
            device.setProductId(productId);
            device.setIotDeviceId(e.getId().toString());
            device.setNodeId(e.getDeviceCode());
            device.setName(e.getDeviceName());
            device.setThirdDeviceId(e.getDeviceCode());
            device.setDeviceTypeId(deviceTypeId);
            Integer online = e.getOnline();
            device.setOnlineStatus(DeviceOnlineStatusEnum.OFFLINE);
            // 物联中台返回1 离线 2 在线
            if (Objects.nonNull(online) && Integer.valueOf(DeviceOnlineStatusEnum.ABNORMAL.getId()).equals(online)) {
                // 业务中台做过转换 此处传1
                device.setOnlineStatus(DeviceOnlineStatusEnum.ONLINE);
            }
            devices.add(device);
        });
        return devices;
    }

    /**
     * 获取设备属性
     * @return
     */
    public Map<String, Object> getDeviceAttribute(String deviceCode) {
        ShadowListVO shadow = new ShadowListVO();
        shadow.setPage(EesdConstant.PAGE_NUM);
        shadow.setCount(EesdConstant.SIZE);
        shadow.setCode(deviceCode);
        JSONObject shadowList = iDeviceCoreWebapiService.deviceShadowList(shadow);
        if (!shadowList.containsKey(EesdConstant.DATA) || Objects.isNull(shadowList.get(EesdConstant.DATA))) {
            return null;
        }
        Map<String, Object> shadows = new HashMap<>();
        List<IotNorthShadowListRespDTO> resultData = Optional.ofNullable(shadowList)
                .map(r -> r.getString(EesdConstant.DATA))
                .map(d -> JSONObject.parseArray(d, IotNorthShadowListRespDTO.class))
                .orElseThrow(() -> new BusinessException("兴海-iot拉取属性值失败result"));
        for (IotNorthShadowListRespDTO resp : resultData) {
            shadows.put(resp.getId(), resp.getCurValue());
        }
        log.info("获取设备：{},所有属性数据：{}", deviceCode, shadows);
        return shadows;
    }


    public List<CoolingScrewDTO> getCoolingScrewData(DeviceProjSupplierCategory config) {
        Integer projectId = config.getProjectId();
        JSONObject properties = config.getProperties();
        Integer deviceTypeId = properties.getInteger("deviceTypeId");
        List<String> deviceCodes = devicesCodeListV1(config, deviceTypeId);
        List<CoolingScrewDTO> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(deviceCodes)) {
            return list;
        }
        Integer productId = config.getProductId();
        LocalDateTime now = LocalDateTime.now();
        //String key = new StringBuilder(KeyConstant.EESD_DEVICE_IDS_MAP).append(projectId).append(":").append(productId).toString();
        for (String deviceCode : deviceCodes) {
            Map<String, Object> map = IotNorthApiUtil.getShadowListV1(config, deviceCode);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
            CoolingScrewDTO dto = null;
            try {
                dto = objectMapper.readValue(JSONObject.toJSONString(map), CoolingScrewDTO.class);
            } catch (Exception e) {
                log.error("Parse exception: {}", e.getMessage());
            }
            //log.info("螺杆机映射字段map：{} ，CoolingScrewDTO:{}", JSONObject.toJSONString(map), JSONObject.toJSONString(dto));
            if (!Objects.isNull(dto)) {
                //String hashKey = deviceCode;
                dto.setProjectId(projectId);
                /*Integer deviceId = Optional.ofNullable(redisUtils.hmGet(key, hashKey))
                        .map(d -> {
                            return JSONObject.parseObject(JSONObject.toJSONString(d), DeviceDTO.class).getId();
                        }).orElse(-1);
                dto.setDeviceId(deviceId);*/
                dto.setThirdDeviceId(deviceCode);
                dto.setUpdateTime(now);
                list.add(dto);
            }
        }
        return list;
    }

    public List<WattHourMeterDTO> getWattHourMeterData(DeviceProjSupplierCategory config) {
        Integer projectId = config.getProjectId();
        JSONObject properties = config.getProperties();
        Integer deviceTypeId = properties.getInteger("deviceTypeId");
        List<String> deviceCodes = devicesCodeListV1(config, deviceTypeId);
        List<WattHourMeterDTO> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(deviceCodes)) {
            return list;
        }
        Integer productId = config.getProductId();
        LocalDateTime now = LocalDateTime.now();
        String key = new StringBuilder(KeyConstant.EESD_DEVICE_IDS_MAP).append(projectId).append(":").append(productId).toString();
        for (String deviceCode : deviceCodes) {
            Map<String, Object> map = IotNorthApiUtil.getShadowListV1(config, deviceCode);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
            WattHourMeterDTO dto = null;
            try {
                dto = objectMapper.readValue(JSONObject.toJSONString(map), WattHourMeterDTO.class);
            } catch (Exception e) {
                log.error("Parse exception: {}", e.getMessage());
            }
            //log.info("电表映射字段map：{} ，WattHourMeterDTO:{}", JSONObject.toJSONString(map), JSONObject.toJSONString(dto));
            if (!Objects.isNull(dto)) {
                //String hashKey = deviceCode;
                dto.setProjectId(projectId);
               /* Integer deviceId = Optional.ofNullable(redisUtils.hmGet(key, hashKey))
                        .map(d -> {
                            return JSONObject.parseObject(JSONObject.toJSONString(d), DeviceDTO.class).getId();
                        }).orElse(-1);
                dto.setDeviceId(deviceId);*/
                dto.setThirdDeviceId(deviceCode);
                dto.setUpdateTime(now);
                list.add(dto);
            }
        }
        return list;
    }


    /*public List<CoolingScrewDTO> getCoolingScrewData(DeviceProjSupplierCategory config) {
        List<CoolingScrewDTO> iotData = getIotData(config, CoolingScrewDTO.class);
        Integer projectId = config.getProjectId();
        Integer productId = config.getProductId();
        String key = new StringBuilder(KeyConstant.EESD_DEVICE_IDS_MAP).append(projectId).append(":").append(productId).toString();
        if (!CollectionUtils.isEmpty(iotData)) {
            for (CoolingScrewDTO dto : iotData) {
                String hashKey = dto.getThirdDeviceId();
                dto.setProjectId(projectId);
                Integer deviceId = Optional.ofNullable(redisUtils.hmGet(key, hashKey)).map(d -> {
                    return JSONObject.parseObject(JSONObject.toJSONString(d), DeviceDTO.class).getId();
                }).orElse(null);
                if (Objects.isNull(deviceId)) {
                    continue;
                }
                dto.setObsTime(LocalDateTime.now());
                dto.setThirdDeviceId(dto.getThirdDeviceId());
            }
        }
        return iotData;
    }*/


    /*****************************************处理设备************************************************/

    public <T> List<T> getIotData(DeviceProjSupplierCategory config, Class<T> clazz) {
        JSONObject properties = config.getProperties();
        Integer deviceTypeId = properties.getInteger("deviceTypeId");
        List<String> deviceCodes = devicesCodeListV1(config, deviceTypeId);
        List<T> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(deviceCodes)) {
            return list;
        }
        for (String deviceCode : deviceCodes) {
            Map<String, Object> map = IotNorthApiUtil.getShadowListV1(config, deviceCode);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            T t = null;
            try {
                t = objectMapper.readValue(JSONObject.toJSONString(map), clazz);
            } catch (Exception e) {
                log.error("iot map to entity class exception: {}", e.getMessage());
            }
            if (!Objects.isNull(t)) {
                list.add(t);
            }
        }
        return list;
    }

    public synchronized List<Device> devices(DeviceProjSupplierCategory config) {
        List<Device> deviceListV1 = IotNorthApiUtil.getDeviceListV1(config);
        return deviceListV1;
    }


    /**
     * 获取iot设备列表code
     * @param config
     * @param deviceTypeId
     * @return
     */
    public List<String> devicesCodeListV1(DeviceProjSupplierCategory config, Integer deviceTypeId) {
        List<Device> deviceList = devices(config);
        List<String> codeList = Optional.ofNullable(deviceList).map(r -> {
            return r.stream().filter(d -> d.getDeviceTypeId().equals(deviceTypeId)).map(Device::getThirdDeviceId).collect(Collectors.toList());
        }).get();
        return codeList;
    }
}
